package com.cfswt.tasksystem.controller;

import com.cfswt.tasksystem.mapper.ProcessCommentMapper;
import com.cfswt.tasksystem.pojo.entity.ProcessComment;
import com.cfswt.tasksystem.response.JsonResult;
import com.cfswt.tasksystem.security.CustomUserDetails;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;


@Slf4j
@RestController
@RequestMapping("/history")
@Api(tags = "70.历史流程管理模块")
public class ActivitiHistoryController {

    @Autowired
    private HistoryService historyService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private TaskRuntime taskRuntime;
    @Autowired
    private ProcessCommentMapper processCommentMapper;

    @ApiOperation(value = "登录用户历史流程列表")
    @GetMapping("")
    public JsonResult getHistoryTaskByUserName(@AuthenticationPrincipal CustomUserDetails userDetails) {
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                .orderByHistoricTaskInstanceEndTime().asc()
                .taskAssignee(userDetails.getUsername())
                .list();
        System.out.println(list);
        return JsonResult.ok(list);
    }

    //当前实例历史任务
    @GetMapping("/{instanceId}")
    public JsonResult getHistoryTaskByInstanceId(@PathVariable String instanceId) {
        System.out.println(instanceId);
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                .orderByHistoricTaskInstanceEndTime().asc()
                .processInstanceId(instanceId)
                .list();
        System.out.println(list);
        return JsonResult.ok(list);
    }
    @ApiOperation(value = "根据当前任务id获取流程实例历史记录")
    @GetMapping("/highLine/task/{taskId}")
    public JsonResult getHighLightShowByTaskId(@PathVariable String taskId,
                                               @AuthenticationPrincipal CustomUserDetails userDetails) {
        Task task = taskRuntime.task(taskId);
        if (task == null) {
            return JsonResult.error(2002, "任务不存在");
        }
        String processInstanceId = task.getProcessInstanceId();
        return getHighLightShowByProcessInstanceId(processInstanceId, userDetails.getUsername());
    }

    @ApiOperation(value = "根据当前流程实例id获取流程实例历史记录")
    @GetMapping("/highLine/process/{processInstanceId}")
    public JsonResult getHighLightShowByProcessInstanceId(@PathVariable String processInstanceId,
                                                          @AuthenticationPrincipal CustomUserDetails userDetails) {
        return getHighLightShowByProcessInstanceId(processInstanceId, userDetails.getUsername());
    }

    private JsonResult getHighLightShowByProcessInstanceId(String processInstanceId, String username) {
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();

        if (historicProcessInstance == null) {
            return JsonResult.error(2002, "流程实例不存在");
        }

        BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
        Process process = bpmnModel.getProcesses().get(0);

        Collection<FlowElement> flowElements = process.getFlowElements();
        HashMap<String, String> sequenceFlowMap = new HashMap<>();
        for (FlowElement flowElement : flowElements) {
            if (flowElement instanceof SequenceFlow) {
                SequenceFlow sequenceFlow = (SequenceFlow) flowElement;
                String sourceRef = sequenceFlow.getSourceRef();
                String targetRef = sequenceFlow.getTargetRef();
                sequenceFlowMap.put(sourceRef + targetRef, sequenceFlow.getId());
            }
        }

        List<HistoricActivityInstance> historicActivityList = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).list();

        HashSet<String> keyList = new HashSet<>();
        for (HistoricActivityInstance activityInstance : historicActivityList) {
            for (HistoricActivityInstance instance : historicActivityList) {
                if (!activityInstance.equals(instance)) {
                    keyList.add(activityInstance.getActivityId() + instance.getActivityId());
                }
            }
        }

        HashSet<String> highLine = new HashSet<>();
        keyList.forEach(s -> {
            String flowId = sequenceFlowMap.get(s);
            if (flowId != null) {
                highLine.add(flowId);
            }
        });

        List<HistoricActivityInstance> listFinished = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).finished().list();
        HashSet<String> highPoint = new HashSet<>();
        listFinished.forEach(s -> highPoint.add(s.getActivityId()));

        List<HistoricActivityInstance> listUnFinished = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).unfinished().list();
        HashSet<String> waitingToDo = new HashSet<>();
        listUnFinished.forEach(s -> waitingToDo.add(s.getActivityId()));

        List<HistoricTaskInstance> listIdo = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(username).processInstanceId(processInstanceId).finished().list();
        HashSet<String> iDo = new HashSet<>();
        listIdo.forEach(s -> iDo.add(s.getTaskDefinitionKey()));

        HashMap<String, Object> reMap = new HashMap<>();
        reMap.put("highPoint", highPoint);
        reMap.put("highLine", highLine);
        reMap.put("waitingToDo", waitingToDo);
        reMap.put("iDo", iDo);

        return JsonResult.ok(reMap);
    }

    @ApiOperation(value = "当前流程实例评论信息")
    @GetMapping("/comment/{taskId}")
    public JsonResult showHistoryComment(@PathVariable String taskId) {
        List<ProcessComment> processCommentList = processCommentMapper.selectCommentByProcessInstanceId(taskRuntime.task(taskId).getProcessInstanceId());
        System.out.println(processCommentList);
        return JsonResult.ok(processCommentList);
    }
}
